using System;

namespace ICSharpCode.TextEditor.Document
{
	public class FoldMarker : AbstractSegment, IComparable
	{
		private bool isFolded = false;

		private string foldText = "...";

		private FoldType foldType = FoldType.Unspecified;

		private IDocument document = null;

		private int startLine = -1;

		private int startColumn;

		private int endLine = -1;

		private int endColumn;

		public FoldType FoldType
		{
			get
			{
				return this.foldType;
			}
			set
			{
				this.foldType = value;
			}
		}

		public int StartLine
		{
			get
			{
				if (this.startLine < 0)
				{
					FoldMarker.GetPointForOffset(this.document, base.offset, out this.startLine, out this.startColumn);
				}
				return this.startLine;
			}
		}

		public int StartColumn
		{
			get
			{
				if (this.startLine < 0)
				{
					FoldMarker.GetPointForOffset(this.document, base.offset, out this.startLine, out this.startColumn);
				}
				return this.startColumn;
			}
		}

		public int EndLine
		{
			get
			{
				if (this.endLine < 0)
				{
					FoldMarker.GetPointForOffset(this.document, base.offset + base.length, out this.endLine, out this.endColumn);
				}
				return this.endLine;
			}
		}

		public int EndColumn
		{
			get
			{
				if (this.endLine < 0)
				{
					FoldMarker.GetPointForOffset(this.document, base.offset + base.length, out this.endLine, out this.endColumn);
				}
				return this.endColumn;
			}
		}

		public override int Offset
		{
			get
			{
				return base.Offset;
			}
			set
			{
				base.Offset = value;
				this.startLine = -1;
				this.endLine = -1;
			}
		}

		public override int Length
		{
			get
			{
				return base.Length;
			}
			set
			{
				base.Length = value;
				this.endLine = -1;
			}
		}

		public bool IsFolded
		{
			get
			{
				return this.isFolded;
			}
			set
			{
				this.isFolded = value;
			}
		}

		public string FoldText => this.foldText;

		public string InnerText => this.document.GetText(base.offset, base.length);

		private static void GetPointForOffset(IDocument document, int offset, out int line, out int column)
		{
			if (offset > document.TextLength)
			{
				line = document.TotalNumberOfLines + 1;
				column = 1;
			}
			else if (offset < 0)
			{
				line = -1;
				column = -1;
			}
			else
			{
				line = document.GetLineNumberForOffset(offset);
				column = offset - document.GetLineSegment(line).Offset;
			}
		}

		public FoldMarker(IDocument document, int offset, int length, string foldText, bool isFolded)
		{
			this.document = document;
			base.offset = offset;
			base.length = length;
			this.foldText = foldText;
			this.isFolded = isFolded;
		}

		public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn)
			: this(document, startLine, startColumn, endLine, endColumn, FoldType.Unspecified)
		{
		}

		public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType)
			: this(document, startLine, startColumn, endLine, endColumn, foldType, "...")
		{
		}

		public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText)
			: this(document, startLine, startColumn, endLine, endColumn, foldType, foldText, isFolded: false)
		{
		}

		public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText, bool isFolded)
		{
			this.document = document;
			startLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(startLine, 0));
			ISegment lineSegment = document.GetLineSegment(startLine);
			endLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(endLine, 0));
			ISegment lineSegment2 = document.GetLineSegment(endLine);
			if (string.IsNullOrEmpty(foldText))
			{
				foldText = "...";
			}
			this.FoldType = foldType;
			this.foldText = foldText;
			base.offset = lineSegment.Offset + Math.Min(startColumn, lineSegment.Length);
			base.length = lineSegment2.Offset + Math.Min(endColumn, lineSegment2.Length) - base.offset;
			this.isFolded = isFolded;
		}

		public int CompareTo(object o)
		{
			if (!(o is FoldMarker))
			{
				throw new ArgumentException();
			}
			FoldMarker foldMarker = (FoldMarker)o;
			if (base.offset != foldMarker.offset)
			{
				return base.offset.CompareTo(foldMarker.offset);
			}
			return base.length.CompareTo(foldMarker.length);
		}
	}
}
